package com.xiaoKe.zhonghzu.global.tool;


import java.math.BigDecimal;
import java.text.DecimalFormat;


public class BigDecimalUtil {

    // 默认精度10, 应该是2,4, 特别是做金额计算，到分和到毫
    public static final int DEFAULT_SCALE = 10;
    // 默认精度 todo 默认精度改成 1
    public static final int DEFAULT_DIV_SCALE = 2;

    // 默认的格式化字符样式 “#.00” 还可以是像“#.0000”
    public static final String DEFAULT_FORMAT_STR = "#.00";

    // 加法
    public static BigDecimal add(BigDecimal v1, BigDecimal v2) {
        return v1.add(v2);
    }

    // 减法
    public static BigDecimal sub(BigDecimal v1, BigDecimal v2) {
        return v1.subtract(v2);
    }

    // 乘法
    public static BigDecimal mul(BigDecimal v1, BigDecimal v2) {
        return v1.multiply(v2);
    }

    // 除法,默认精度
    public static BigDecimal div(BigDecimal v1, BigDecimal v2) {
        return div(v1, v2, DEFAULT_DIV_SCALE);
    }

    // 对一个double截取指定的长度,利用除以1实现
    public static BigDecimal round(BigDecimal v1, int scale) {
        if (scale < 0) {
            new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = v1;
        BigDecimal b2 = new BigDecimal("1");
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
    }

    // 除法,自定义精度
    public static BigDecimal div(BigDecimal v1, BigDecimal v2, int scale) {
        // 如果分母为0 直接返回
        if (BigDecimalUtil.valuesEquals(v2, BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }

        if (scale < 0) {
            new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        return v1.divide(v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    // 比较2个double值，相等返回0，大于返回1，小于返回-1
    public static int compareTo(BigDecimal v1, BigDecimal v2) {
        return v1.compareTo(v2);
    }

    // 判断2个BigDecimal 的值相等这里要改，相等返回true,否则返回false
    public static boolean valuesEquals(BigDecimal v1, BigDecimal v2) {
        boolean result;
        int resultInt = v1.compareTo(v2);
        if (resultInt == 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // 判断2个BigDecimal 的值,v1大于v2返回true,否则返回false
    public static boolean valuesGreater(BigDecimal v1, BigDecimal v2) {
        boolean result;
        int resultInt = v1.compareTo(v2);
        if (resultInt > 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // 判断2个BigDecimal 的值,v1小于v2返回true,否则返回false
    public static boolean valuesLess(BigDecimal v1, BigDecimal v2) {
        boolean result;
        int resultInt = v1.compareTo(v2);
        if (resultInt < 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // 加法
    public static BigDecimal add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }

    // 减法
    public static BigDecimal sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2);
    }

    // 乘法
    public static BigDecimal mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2);
    }

    // 除法,默认精度
    public static BigDecimal div(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
    }

    // 对一个double截取指定的长度,利用除以1实现
    public static BigDecimal round(double v1, int scale) {
        if (scale < 0) {
            new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal("1");
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
    }

    // 除法,自定义精度
    public static BigDecimal div(double v1, double v2, int scale) {
        if (scale < 0) {
            new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        // 如果分母为0 直接返回
        if (BigDecimalUtil.valuesEquals(b2, BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
    }

    // 比较2个double值，相等返回0，大于返回1，小于返回-1
    public static int compareTo(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.compareTo(b2);
    }

    // 比较v1是否在 {v2, v3] 之间
    public static Boolean between(BigDecimal v1, BigDecimal v2, BigDecimal v3) {
        return v1.compareTo(v2) >= 0 && v1.compareTo(v3) < 0;
    }

    // 比较v1是否在 {v2, v3} 之间
    public static Boolean betweenAndEq(BigDecimal v1, BigDecimal v2, BigDecimal v3) {
        if (v2 == null) {
            return v1.compareTo(v3) <= 0;
        }
        if (v3 == null) {
            return v1.compareTo(v2) >= 0;
        }
        return v1.compareTo(v2) >= 0 && v1.compareTo(v3) <= 0;
    }

    // 判断2个double的值相等这里要改，相等返回true,否则返回false
    public static boolean valuesEquals(double v1, double v2) {
        boolean result;
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        int resultInt = b1.compareTo(b2);
        if (resultInt == 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // 判断2个double的值,v1大于v2返回true,否则返回false
    public static boolean valuesGreater(double v1, double v2) {
        boolean result;
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        int resultInt = b1.compareTo(b2);
        if (resultInt > 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // 判断2个double的值,v1小于v2返回true,否则返回false
    public static boolean valuesLess(double v1, double v2) {
        boolean result;
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        int resultInt = b1.compareTo(b2);
        if (resultInt < 0) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    // DecimalFormat格式化，使用默认的格式样式
    public static String format(Object object) {
        return new DecimalFormat(DEFAULT_FORMAT_STR).format(object);
    }

    // DecimalFormat格式化，使用传入的字符串格式样式
    public static String format(Object object, String formatStr) {
        return new DecimalFormat(formatStr).format(object);
    }

    //取绝对值
    public static BigDecimal abs(BigDecimal val) {
        if (valuesLess(val, BigDecimal.ZERO)) {
            return mul(val, new BigDecimal(-1));
        }
        return val;
    }

    /**
     * 去掉多余的0
     */
    public static String stripTrailingZeros(BigDecimal bigDecimal) {
        return null != bigDecimal ? bigDecimal.stripTrailingZeros().toPlainString() : "0";
    }
    public static String stripTrailingZeros(String str) {
        if (null==str){
            return "0";
        }
        BigDecimal bigDecimal = new BigDecimal(str);
        return null != bigDecimal ? bigDecimal.stripTrailingZeros().toPlainString() : "0";
    }


    public static String stripTrailingZeros(BigDecimal bigDecimal, int index) {
        return null != bigDecimal ? bigDecimal.setScale(index, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString() : "0";
    }

    public static String stripTrailingZeros(double bigDecimal, int index) {
        return null != bigDecimal + "" ? new BigDecimal(bigDecimal).setScale(index, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString() : "0";
    }

    public static BigDecimal toBigDecimal(String str) {
        return null != str ? new BigDecimal(str) : new BigDecimal("0");
    }
}

